const fs = require('fs');
const path = require('path');

// 进制字符映射（最大支持36进制）
const DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

/**
 * 获取数值在指定进制下的首字符
 * @param {number} number - 要转换的数值
 * @param {number} base - 进制基数 (2-36)
 * @returns {string} 首字符
 */
function getLeadingDigit(number, base) {
  if (base < 2 || base > 36) throw new Error('进制基数需在2-36之间');
  if (number === 0) return '0';

  let value = number;
  while (value >= base) {
    value = Math.floor(value / base);
  }
  return DIGITS[value].toUpperCase();
}

/**
 * 统计文件大小首字符分布
 * @param {string} directory - 要扫描的目录
 * @param {number} [base=10] - 进制基数
 */
async function analyzeSizeDistribution(directory, base = 10) {
  // 初始化分组
  const sizeGroups = Array.from({ length: base - 1 }, (_, i) =>
    getLeadingDigit(i + 1, base)
  ).reduce((acc, char) => (acc[char] = 0, acc), {});

  let totalSize = 0;

  // 递归遍历目录
  function traverse(dir) {
    try {
      const items = fs.readdirSync(dir, { withFileTypes: true });
      for (const dirent of items) {
        const fullPath = path.join(dir, dirent.name);
        try {
          if (dirent.isDirectory()) {
            traverse(fullPath);
          } else if (dirent.isFile()) {
            const { size } = fs.statSync(fullPath);
            if (size === 0) continue;

            const leadingChar = getLeadingDigit(size, base);
            if (sizeGroups.hasOwnProperty(leadingChar)) {
              sizeGroups[leadingChar] += size;
              totalSize += size;
            }
          }
        } catch (err) {
          console.error(`[跳过] ${fullPath}`);
        }
      }
    } catch (err) {
      console.error(`[错误] 无法访问目录: ${dir}`);
    }
  }

  traverse(directory);

  // 生成结果
  return {
    base,
    totalSize,
    distribution: Object.entries(sizeGroups).map(([char, size]) => ({
      char,
      size,
      percentage: totalSize > 0
        ? (size / totalSize * 100).toFixed(2) + '%'
        : '0.00%'
    }))
  };
}

// 可视化输出函数
function visualize(result) {
  console.log(`\n进制基数: ${result.base}`);
  console.log(`总文件大小: ${(result.totalSize / 1024 ** 3).toFixed(2)} GB`);
  console.log('首字符分布:');

  const maxBarWidth = 40;
  const maxValue = Math.max(...result.distribution.map(d => d.size));

  result.distribution
    .sort((a, b) => b.size - a.size)
    .forEach(({ char, size, percentage }) => {
      const barWidth = Math.round(size / maxValue * maxBarWidth);
      console.log(
        `${char.padStart(2)} | ${'█'.repeat(barWidth).padEnd(maxBarWidth)} | ` +
        `${percentage.padStart(6)} (${(size / 1024 ** 2).toFixed(2)} MB)`
      );
    });
}

// 使用示例（扫描D盘，使用20进制）
analyzeSizeDistribution('D:\\', 20)
  .then(visualize)
  .catch(console.error);